package apple.ui.swt;

import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;

import apple.core.KeyboardDecoder;

public class Keyboard implements KeyListener {

   static Logger logger = Logger.getLogger(Keyboard.class);

   private KeyboardDecoder keyboardDecoder;

   public void setKeyboardDecoder(KeyboardDecoder keyboardDecoder) {
      this.keyboardDecoder = keyboardDecoder;
   }

   /*
    * (non-Javadoc)
    * 
    * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
    */
   @Override
   public void keyPressed(KeyEvent e) {
      int keyCode = e.keyCode;
      Integer asciiCode = null;

      switch (keyCode) {

      case 0x08:
         asciiCode = 0x7F;
         logger.debug(String.format("remapping key: %02X to %02X", keyCode,
               asciiCode));
         break;

      case 0x1000003:
         asciiCode = 0x08;
         logger.debug(String.format("remapping key: %02X to %02X", keyCode,
               asciiCode));
         break;

      case 0x1000002:
         asciiCode = 0x0A;
         logger.debug(String.format("remapping key: %02X to %02X", keyCode,
               asciiCode));
         break;

      case 0x1000001:
         asciiCode = 0x0B;
         logger.debug(String.format("remapping key: %02X to %02X", keyCode,
               asciiCode));
         break;

      case 0x1000004:
         asciiCode = 0x15;
         logger.debug(String.format("remapping key: %02X to %02X", keyCode,
               asciiCode));
         break;

      case 0x09:
      case 0x0D:
      case 0x1B:
      case 0x20:
         asciiCode = keyCode;
         break;

      case 0x2D:
         if ((e.stateMask & SWT.CONTROL) != 0) {
            asciiCode = 0x1F;
         } else {
            asciiCode = (int) e.character;
         }
         break;

      case 0x32:
         if ((e.stateMask & SWT.CONTROL) != 0) {
            asciiCode = 0x00;
         } else {
            asciiCode = (int) e.character;
         }
         break;

      case 0x36:
         if ((e.stateMask & SWT.CONTROL) != 0) {
            asciiCode = 0x1E;
         } else {
            asciiCode = (int) e.character;
         }
         break;

      case 0x5B:
         if ((e.stateMask & SWT.CONTROL) != 0) {
            asciiCode = 0x1B;
         } else {
            asciiCode = (int) e.character;
         }
         break;

      case 0x5C:
         if ((e.stateMask & SWT.CONTROL) != 0) {
            asciiCode = 0x1C;
         } else {
            asciiCode = (int) e.character;
         }
         break;

      case 0x5D:
         if ((e.stateMask & SWT.CONTROL) != 0) {
            asciiCode = 0x1D;
         } else {
            asciiCode = (int) e.character;
         }
         break;

      case 0x27:
      case 0x2C:
      case 0x2E:
      case 0x2F:
      case 0x30:
      case 0x31:
      case 0x33:
      case 0x34:
      case 0x35:
      case 0x37:
      case 0x38:
      case 0x39:
      case 0x3B:
      case 0x3D:
      case 0x60:
      case 0x61:
      case 0x62:
      case 0x63:
      case 0x64:
      case 0x65:
      case 0x66:
      case 0x67:
      case 0x68:
      case 0x69:
      case 0x6A:
      case 0x6B:
      case 0x6C:
      case 0x6D:
      case 0x6E:
      case 0x6F:
      case 0x70:
      case 0x71:
      case 0x72:
      case 0x73:
      case 0x74:
      case 0x75:
      case 0x76:
      case 0x77:
      case 0x78:
      case 0x79:
      case 0x7A:
         asciiCode = (int) e.character;
         break;

      default:
         logger.debug(String.format("key pressed: keycode: %02X (ignored)",
               keyCode));
         break;
      }

      if (asciiCode != null) {
         logger
               .debug(String.format("key pressed: ascii code: %02X", asciiCode));
         keyboardDecoder.setAsciiCodeAndStrobe(asciiCode.byteValue());
         keyboardDecoder.setKeyDown(true);
      }
   }

   /*
    * (non-Javadoc)
    * 
    * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
    */
   @Override
   public void keyReleased(KeyEvent e) {
      keyboardDecoder.setKeyDown(false);
   }
}
